package com.youyicloud.config;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.ServletInputStreamWrapper;
import com.youyicloud.entity.FilterPath;
import com.youyicloud.entity.UserInfo;
import com.youyicloud.utils.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StreamUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;

@Slf4j
public class CheckTokenPreFilter extends ZuulFilter{

	@Autowired
	private JdbcTemplate jdbcTemplate;

	//决定此过滤器是否执行
	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String actionUrl = request.getRequestURI();

		List<FilterPath> filterPaths = jdbcTemplate.query("select * from t_filter_path", new
				BeanPropertyRowMapper<FilterPath>(FilterPath.class));

		log.info("请求地址:{}",actionUrl);
		for(FilterPath filterPath : filterPaths){
			if(actionUrl.indexOf(filterPath.getPath())!=-1){
				ctx.set("isSuccess",false);
				return false;
			}
		}
		return true;
	}
	
	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String actionUrl = request.getRequestURI();
		String token = request.getParameter("token");
		if(StringUtils.isNotBlank(token)){
			log.info("token:{}",token);
			String userName = JWTUtil.getUsername(token);
			Integer userId = 0;
			try {
				userId=Integer.parseInt(userName);
			}catch (Exception e) {
				ctx.setSendZuulResponse(false);
				ctx.setResponseStatusCode(200);
				ctx.set("isSuccess",false);
				ctx.setResponseBody("{\"result\":\"token Invalid\",\"code\":1005}");
				return null;
			}
			UserInfo userInfo = null;
			/*if(actionUrl.indexOf("mascot")!=-1) {
				userInfo = mascotFeignClients.findByUserId(userId).get(0);
			}else {
				userInfo = feignClients.findUserById(userId);
			}*/
			if(JWTUtil.verify(token, userName, userInfo.getPassword())) {//校验用户名密码是否过期
				ctx.setSendZuulResponse(true);
				ctx.setResponseStatusCode(HttpStatus.OK.value());
				ctx.set("isSuccess",true);
				String newToken = JWTUtil.sign(userId+"",userInfo.getPassword());
				// 在json参数中添加 userId
				try {
					InputStream in = ctx.getRequest().getInputStream();
					String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
					String newBody = StringUtils.replace(body,  "token=" + token, "token=" + newToken);
					final byte[] reqBodyBytes = newBody.getBytes();
					ctx.setRequest(new HttpServletRequestWrapper(request){
						@Override
						public ServletInputStream getInputStream() throws IOException {
							return new ServletInputStreamWrapper(reqBodyBytes);
						}
						@Override
						public int getContentLength() {
							return reqBodyBytes.length;
						}
						@Override
						public long getContentLengthLong() {
							return reqBodyBytes.length;
						}
					});
				} catch (IOException e) {
					e.printStackTrace();
				}
				log.info("进入下一步请求:{}",token);
			}else {
				ctx.setSendZuulResponse(false);
				ctx.setResponseStatusCode(200);
				ctx.set("isSuccess",false);
				ctx.setResponseBody("{\"result\":\"token rechargeRecord\",\"code\":1004}");
			}
		}else{
			ctx.setSendZuulResponse(false);
			ctx.setResponseStatusCode(200);
			ctx.set("isSuccess",false);
			ctx.setResponseBody("{\"result\":\"token is null\",\"code\":1003}");
		}
		return null;
	}

	

	@Override
	public int filterOrder() {
		return 0;
	}

	/**
	PRE过滤器: 在请求被路由之前调用, 可用来实现身份验证、在集群中选择请求的微服务、记录调试信息等;
	ROUTING过滤器: 在路由请求时候被调用;
	POST过滤器: 在路由到微服务以后执行, 可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等;
	ERROR过滤器: 在处理请求过程时发生错误时被调用
	 */
	@Override
	public String filterType() {
		return "pre";
	}

	
}
